package org.zero.controller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author Zero
 */
@Controller
@RequestMapping("/file")
public class FileController {
    /**
     * 传统方式上传文件
     *
     * @param request
     */
    @RequestMapping(path = "upload1", method = RequestMethod.POST)
    public String fileUpload1(HttpServletRequest request) {
        //判断请求提交的方式是否为“multipart/form-data”类型
        if (ServletFileUpload.isMultipartContent(request)) {
            DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
            ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);

            //设置文件存放路径
            String path = request.getServletContext().getRealPath("/uploads/");
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }

            //根据表单项解析表单
            try {
                //解析表单项到List
                List<FileItem> fileItems = servletFileUpload.parseRequest(request);
                for (FileItem fileItem : fileItems) {
                    //判断其是否为普通表单项
                    if (fileItem.isFormField()) {
                        if ("username".equals(fileItem.getFieldName())) {
                            System.out.println(fileItem.getString("utf-8"));
                        }
                    } else {
                        /*重新生成文件名
                         * 1、（上传者+）UUID+原文件名
                         * 2、（上传者+）时间戳+原文件名
                         */
                        String name = System.currentTimeMillis() + "_" + fileItem.getName();
                        //存储文件
                        fileItem.write(new File(path, name));
                        //删除临时文件
                        fileItem.delete();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return "upload-failed";
            }

            //根据表单项name属性解析表单
//            try {
//                //解析表单项到Map
//                Map<String, List<FileItem>> fileItemMap = servletFileUpload.parseParameterMap(request);
//                //获取指定表单项并进行处理
//                List<FileItem> fileItems = fileItemMap.get("file");
//                for (FileItem fileItem : fileItems) {
//                    /*重新生成文件名
//                     * 1、（上传者+）UUID+原文件名
//                     * 2、（上传者+）时间戳+原文件名
//                     */
//                    String name = UUID.randomUUID() +"_"+ fileItem.getName();
//                    //存储文件
//                    fileItem.write(new File(path, name));
//                    //删除临时文件
//                    fileItem.delete();
//                }
//            } catch (FileUploadException e) {
//                e.printStackTrace();
//            } catch (Exception e) {
//                e.printStackTrace();
//                return "upload-failed";
//            }
            return "upload-success";
        }
        return "upload-failed";
    }

    /**
     * springmvc方式上传文件
     *
     * @param request
     * @param username
     * @param multipartFile 单文件上传用 MultipartFile，多文件用List<MultipartFile>
     * @return
     */
    @RequestMapping("/upload2")
    public String fileUpload2(HttpServletRequest request, @RequestParam String username, @RequestParam("file") MultipartFile multipartFile) {
        if (!multipartFile.isEmpty()) {
            try {
                //设置文件存放路径
                String path = request.getServletContext().getRealPath("/uploads/");
                File file = new File(path);
                if (!file.exists()) {
                    file.mkdirs();
                }

                String name = username + "_" + UUID.randomUUID().toString().replace("-", "") + "_" + multipartFile.getOriginalFilename();
                multipartFile.transferTo(new File(path, name));
            } catch (Exception e) {
                e.printStackTrace();
                return "upload-failed";
            }
            return "upload-success";
        }
        return "upload-failed";
    }

    @RequestMapping("/upload3")
    public String fileUpload3(HttpServletRequest request, @RequestParam("file") MultipartFile multipartFile) {
        if (!multipartFile.isEmpty()) {
            try {
                //设置文件存放路径
                String path = "http://localhost:9090/uploads/";

                String name = UUID.randomUUID().toString().replace("-", "") + "_" + multipartFile.getOriginalFilename();

                // 创建客户端的对象
                Client client = Client.create();
                // 和图片服务器进行连接
                WebResource webResource = client.resource(path + name);
                // 上传文件
                webResource.put(multipartFile.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
                return "upload-failed";
            }
            return "upload-success";
        }
        return "upload-failed";
    }

    @RequestMapping("/download")
    public ResponseEntity<byte[]> fileDownload(HttpServletRequest request, String filename, @RequestHeader("User-Agent") String userAgent) {
        try {
            //获取文件下载位置
            String path = request.getServletContext().getRealPath("/uploads/");
            File file = new File(path + File.separator + filename);
            HttpHeaders httpHeaders = new HttpHeaders();

            //IE11的用户代理字串已经修改，不再是“MSIE”了，而改成了“like Gecko”
            String[] keywords = {"MSIE", "like Gecko", "Trident"};
            // 根据浏览器类型，决定处理方式
            //IE内核浏览器，统一为utf-8编码显示
            boolean isIE = false;
            for (String keyword : keywords) {
                if (userAgent.contains(keyword)) {
                    filename = URLEncoder.encode(filename, "utf-8");
                    isIE = true;
                    break;
                }
            }
            //火狐等其他浏览器统一为ISO-8859-1编码显示
            if (!isIE) {
                filename = new String(filename.getBytes(StandardCharsets.UTF_8), "ISO-8859-1");
            }

            httpHeaders.setContentDispositionFormData("attachment", filename);
            httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), httpHeaders, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
